/** 
 * @Title: ATest.java 
 * @Package com.zizo.test 
 * @Description: TODO
 * @author HeYan
 * @date 2016年10月25日 下午4:07:19 
 */
package com.zizo.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.common.Term;
import com.zizo.util.ConnectionPool;

/**
 * @ClassName: ATest
 * @Description: TODO
 * @author HeYan
 * @date 2016年10月25日 下午4:07:19
 * 
 */
public class AudiRelationShip implements Runnable {
	private String tablename;
	private Connection conn;
	private Map<String, Double> mapRes;

	public AudiRelationShip(String tablename, Connection conn) {
		super();
		this.tablename = tablename;
		this.conn = conn;
		this.mapRes = new HashMap<>();
	}

	/**
	 * @Title: readFileContent
	 * @Description: TODO 读取文件的内容
	 * @throws IOException
	 * @return void
	 * @author HeYan
	 */
	public final void readFileContent() throws IOException {
		File file = new File("/var/server/java/heyan/" + "a.txt");
		FileReader fr = new FileReader(file);
		BufferedReader br = new BufferedReader(fr);
		file = null;
		String temp = "";
		while ((temp = br.readLine()) != null) {
			calculate(temp);
		}
		temp = null;
		fr.close();
		br.close();
	}

	final static String s = "^的$|^了$|^我$|^是$|^在$|^有$|^就$|^也$|^一$|^都$|^个$|^和$|^说$|^这$|^要$|^去$|^还$|^到$|^啊$|^你$|^吗$|^给$|^看$|^就是$|^吧$|^呀$|^但$|^为$|^及$|^我的$|^我们$|^你们$|^刚$|^总体$|^因为$|^所以$|^但是$|^方面$|^可能$|^还是$|^这是$|^那$|^那是$|^能$|^呢$|^才$|^那么$|^这么$|^然后$|^然而$|^只有$|^什么$|^总的来说$|^哪个$|^到底$|^不知$|^这些$|^那些$|^射精$|^版主$|^认证$";
	final static Pattern p_1 = Pattern.compile(s);

	/**
	 * @Title: getFilterData
	 * @Description: TODO 去掉停止词
	 * @param content
	 * @return
	 * @return String
	 * @author Alexis
	 */
	public static final String getFilterData(String content) {
		Matcher m_1 = p_1.matcher(content);
		String res_1 = m_1.replaceAll("");
		m_1 = null;
		return res_1;
	}

	/**
	 * @Title: calculate
	 * @Description: TODO 计算词对关系
	 * @param content
	 * @return void
	 * @author HeYan
	 */
	public final void calculate(String content) {
		String[] cs = content.split("\n");
		for (String s : cs) {
			List<Term> wordTerm = HanLP.segment(s.trim().toUpperCase());// 该段话中所有的分词集合
			Map<String, Integer> map = new HashMap<>();// 计算一段话中每个词对应出现的次数
			for (Term term : wordTerm) {
				String word = getFilterData(term.word);
				if (word.length() == 0) {
					continue;
				}
				if (map.containsKey(word)) {
					map.put(word, map.get(word) + 1);
				} else {
					map.put(word, 1);
				}
				word = null;
			}
			wordTerm = null;
			Object[] arr = map.keySet().toArray();
			int size = arr.length;
			/* 标点‘’“”：:'"?？}{ */
			for (int i = 0; i < size; i++) {
				for (int j = i + 1; j < size; j++) {
					String w1 = (String) arr[i];
					String w2 = (String) arr[j];
					if (isEquals(w1) || isEquals(w2)) {
						w1 = null;
						w2 = null;
						continue;
					}
					int c1 = map.get(w1);
					int c2 = map.get(w2);
					int n0 = c1 > c2 ? c2 : c1;// 共现频次
					/* 计算俩个词之间 }{ 的平均个数 */
					double x = getAvgCount(w1, w2, c1, c2, s.toUpperCase().trim());
					if (x == 0) {
						continue;
					}
					double res = n0 / (Math.pow(1.3, x));
					String key = w1.hashCode() >= w2.hashCode() ? w1 + "%%" + w2 : w2 + "%%" + w1;
					if (mapRes.containsKey(key)) {
						mapRes.put(key, mapRes.get(key) + res);
					} else {
						mapRes.put(key, res);
					}
				}
			}
		}
	}

	public static final boolean isEquals(String s) {
		if (s.contains("}{")) {
			return true;
		} else {
			boolean ss = s.matches(".*['|\"|:|：|‘|’|“|”|\\(|\\)|（|）|？|\\?|\\[|\\]|【|】|\\)\\{\\}|\\-|/|//].*");
			return ss;
		}
	}

	/**
	 * @Title: getAvgCount
	 * @Description: TODO 计算俩个词之间 }{ 的平均个数
	 * @param w1
	 * @param w2
	 * @param c1
	 * @param c2
	 * @param sentence
	 * @return
	 * @return double
	 * @author HeYan
	 */
	public final double getAvgCount(String w1, String w2, int c1, int c2, String sentence) {
		List<Integer> list1 = new ArrayList<>();
		List<Integer> list2 = new ArrayList<>();
		String temp;
		int first = 0;
		for (int i = 0; i < c1; i++) {
			if (i != 0) {
				temp = sentence.substring(first + w1.length());
				int t = first;
				first = temp.indexOf(w1);
				list1.add(first + t + w1.length());
			} else {
				temp = sentence;
				first = temp.indexOf(w1);
				list1.add(first);
			}
		}
		for (int i = 0; i < c2; i++) {
			if (i != 0) {
				temp = sentence.substring(first + w2.length());
				int t = first;
				first = temp.indexOf(w2);
				list2.add(first + t + w2.length());
			} else {
				temp = sentence;
				first = temp.indexOf(w2);
				list2.add(first);
			}
		}
		temp = null;
		/* 计算 */
		double sum = 0;
		for (int i : list1) {
			for (int j : list2) {
				if (i >= j) {
					sum += sentence.substring(j, i + w1.length())
							.split("\\(|\\)|（|）|'|‘|’|“|”|\"|:|：|\\}\\{|\\?|？|【|】|\\[|\\]").length - 1;
				} else {
					sum += sentence.substring(i, j + w2.length())
							.split("\\(|\\)|（|）|'|‘|’|“|”|\"|:|：|\\}\\{|\\?|？|【|】|\\[|\\]").length - 1;
				}
			}
		}
		return sum / (c1 * c2);
	}

	public void insertRes(String w1, String w2, double res) {
		PreparedStatement ps = null;
		String sql = "INSERT INTO relationship_0115(word1,word2,p) VALUES(?,?,?)";
		try {
			ps = conn.prepareStatement(sql);
			ps.setString(1, w1);
			ps.setString(2, w2);
			ps.setDouble(3, res);
			ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public void createTable() {
		String s = "DROP TABLE If exists relationship_0115";
		String sql = "CREATE TABLE relationship_0115 like relationship";
		Statement st = null;
		try {
			st = conn.createStatement();
			st.executeUpdate(s);
			st.executeUpdate(sql);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				st.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public void run() {
		createTable();
		try {
			readFileContent();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println(tablename + " is inserting");
		for (Map.Entry<String, Double> entry : mapRes.entrySet()) {
			String[] words = entry.getKey().split("%%");
			String w1 = words[0];
			String w2 = words[1];
			insertRes(w1, w2, entry.getValue());
			words = null;
			w1 = null;
			w2 = null;
		}
		System.out.println(tablename);
	}

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		ExecutorService fix = Executors.newFixedThreadPool(10);
		Connection conn = ConnectionPool.getConnection("carvoice_autohome", "localhost", "3306");
		fix.execute(new AudiRelationShip("a.txt", conn));
		fix.shutdown();
		while (true) {
			if (fix.isTerminated()) {
				System.out.println((System.currentTimeMillis() - start) / (1000) + "S");
				break;
			} else {
				try {
					Thread.sleep(1000 * 5);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
